package com.towexin.application.system.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.towexin.application.system.domain.AuthorityMenu;
import com.towexin.application.system.domain.Menu;
import com.towexin.application.system.mapper.MenuMapper;
import com.towexin.application.system.service.AuthorityMenuService;
import com.towexin.application.system.service.MenuService;
import com.towexin.utils.TemplateFileTool;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.util.StringUtils;

import java.util.*;

/**
 * TODO
 *
 * @author Towexin
 * @version 1.0
 * @date 2021/4/11 20:53
 */
@Service
@Transactional
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {
    @Autowired
    private AuthorityMenuService authorityMenuService;

    // 级联批量删除菜单
    @Override
    public boolean deleteCascadeMore(List<String> ids) {
        List<Menu> menus = list();
        List<String> urls = new ArrayList<>();

        for (Menu menu : menus) {
            for (String id : ids) {
                if (menu.getId().equals(id)) {
                    if (!StringUtils.isEmpty(menu.getMenuHref())) {
                        urls.add(menu.getMenuHref());
                    }
                    urls.addAll(getCascadeUrl(menu.getId(), menus));
                }
            }
        }

        for (String id : ids) {
            ids.addAll(getCascadeId(id, menus));
        }

        if (this.removeByIds(ids)) {
            boolean flag = true;
            for (String url : urls) {
                //flag = TemplateFileTool.deleteHtml(url);
            }
            return flag;
        }

        return false;
    }

    // 级联删除菜单
    @Override
    public boolean deleteCascade(String id) {
        List<String> ids = new ArrayList<>();
        ids.add(id);
        ids.addAll(getCascadeId(id, this.list()));
        // return this.removeByIds(ids);

        List<String> urls = new ArrayList<>();
        List<Menu> menus = this.list();
        for (Menu menu : menus) {
            if (menu.getId().equals(id)) {
                if (!StringUtils.isEmpty(menu.getMenuHref()))
                    urls.add(menu.getMenuHref());
                urls.addAll(getCascadeUrl(menu.getId(), menus));
            }
        }
        if (removeByIds(ids)) {
            boolean flag = true;
            // for (String url:urls){
            // flag = TemplateFileTool.deleteHtml(url);
            // }
            return flag;
        }
        return false;
    }

    // 添加或更新菜单
    @Override
    public boolean saveOrUpdateMenu(Menu menu) {
        menu.setOpen(true);
        if (StringUtils.isEmpty(menu.getId()))
            menu.setStatus(true);

        // 为了方便开发啊设置新增菜单创建页面
        if (this.saveOrUpdate(menu)) {
            if (!StringUtils.isEmpty(menu.getMenuHref()) && menu.getPage()) {
                return TemplateFileTool.createHtml(menu.getMenuName(), menu.getMenuHref());
            }
            return true;
        }
        return false;

        // return this.saveOrUpdate(menu);
    }

    @Override
    public boolean changeStatus(String id, Boolean status) {
        Menu menu = new Menu();
        menu.setId(id);
        menu.setStatus(status);
        return updateById(menu);
    }

    // 系统菜单渲染显示
    @Override
    public Map<String, Object> menuRendering() {
        Subject subject = SecurityUtils.getSubject();
        List<Menu> menus = baseMapper.selectAuthorityMenuByUserName(subject.getPrincipal().toString());
        Map<String, Object> map = new HashMap<>();

        Map<String, Object> homePage = new HashMap<>();
        homePage.put("title", "后台首页");
        homePage.put("href", "page/err/404");
        for (Menu menu : menus) {
            if (menu.getType() == 1 && menu.getStatus()) {
                homePage.put("title", menu.getMenuName());
                homePage.put("href", menu.getMenuHref());
                break;
            }
        }

        map.put("homeInfo", homePage);
        map.put("pageInfo", MenuRenderingRecursion("no", menus));

        return map;
    }

    @Override
    public List<Map<String, Object>> newMenuRendering() {
        Subject subject = SecurityUtils.getSubject();
        Set<Menu> set = new HashSet<>(baseMapper.selectAuthorityMenuByUserName(subject.getPrincipal().toString()));
        set.addAll(baseMapper.selectDefaultMenu());
		List<Menu> menus = new ArrayList<>(set);

        menus.sort((m1, m2) -> {
			int sort1 = m1.getSort() != null ? m1.getSort() : 0;
			int sort2 = m2.getSort() != null ? m2.getSort() : 0;
			if (sort1 - sort2 > 0) {
				return 1;
			} else if (sort1 - sort2 < 0) {
				return -1;
			}
			return 0;
		});

        return MenuRenderingRecursion("no", menus);
    }

    // 根据用户权限获取菜单
    @Override
    public List<Menu> selectAll() {
        // 获取没有绑定权限的菜单
        return baseMapper.selectAuthorityMenuByUserName(SecurityUtils.getSubject().getPrincipal().toString());
    }

    // 获取菜单树(选择菜单时用)
    @Override
    public List<Map<String, Object>> selectMenuTree() {
        Map<String, Object> menuMap = new HashMap<>();
        menuMap.put("title", "根菜单");
        menuMap.put("value", "no");
        menuMap.put("children", selectMenuTreeRecursion("no", null, selectAll(), null, false));
        List<Map<String, Object>> mapList = new ArrayList<>();
        mapList.add(menuMap);
        return mapList;
    }

    // 获取子菜单
    @Override
    public List<Map<String, Object>> selectMenuTreeByPid(String pId, String id) {
        List<AuthorityMenu> authorityMenus = authorityMenuService.list();
        List<String> amIds = new ArrayList<>();
        for (AuthorityMenu authorityMenu : authorityMenus) {
            amIds.add(authorityMenu.getMId());
        }
        return selectMenuTreeRecursion(pId, id, selectAll(), amIds, true);
    }

    // 菜单树递归 flag=true时获取包括后台首页
    protected List<Map<String, Object>> selectMenuTreeRecursion(String pId, String id, List<Menu> menus,
                                                                List<String> ids, boolean flag) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (Menu menu : menus) {
            Map<String, Object> map = new HashMap<>();
            if (!flag) {
                // 添加菜单是获取上级菜单走此分支
                if (menu.getType() == 0 && !menu.getPage() && menu.getPId().equals(pId)) {
                    map.put("title", menu.getMenuName());
                    map.put("value", menu.getId());
                    map.put("children", selectMenuTreeRecursion(menu.getId(), id, menus, ids, false));
                    if (!menu.getStatus())
                        map.put("title", map.get("title") + "【菜单未启用】");
                    mapList.add(map);
                }
            } else {
                // 获取未关联权限的菜单
                if (menu.getPId().equals(pId)) {
                    map.put("title", menu.getMenuName());
                    map.put("value", menu.getId());
                    map.put("children", selectMenuTreeRecursion(menu.getId(), id, menus, ids, true));
                    if (ids.contains(menu.getId())) {
                        map.put("title", menu.getMenuName() + "【已关联】");
                        if (id == null || !Objects.equals(id, menu.getId())) {
                            map.put("disabled", true);
                        } else {
                            map.put("title", menu.getMenuName() + "【当前关联】");
                        }
                    }
                    if (!menu.getStatus())
                        map.put("title", map.get("title") + "【菜单未启用】");
                    mapList.add(map);
                }
            }

        }
        return mapList;
    }

    // 菜单渲染递归
    protected List<Map<String, Object>> MenuRenderingRecursion(String pId, List<Menu> menus) {
        List<Map<String, Object>> newMenu = new ArrayList<>();
        for (Menu menu : menus) {
            if (menu.getType() == 0 && menu.getStatus()) {
                if (pId.equals(menu.getPId())) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("title", menu.getMenuName());
                    map.put("href", menu.getMenuHref());
                    map.put("target", menu.getTarget());
                    map.put("type", 1);
                    map.put("icon", menu.getIcon());
                    map.put("id", menu.getId());
                    if (StringUtils.isEmpty(menu.getMenuHref())) {
                        map.put("type", 0);
                        map.put("hasChild", true);
                        map.put("childs", MenuRenderingRecursion(menu.getId(), menus));
                    }
                    newMenu.add(map);
                }
            }
        }
        return newMenu;
    }

    // 获取级联id
    protected List<String> getCascadeId(String id, List<Menu> menus) {
        List<String> ids = new ArrayList<>();
        for (Menu menu : menus) {
            if (menu.getPId().equals(id)) {
                ids.add(menu.getId());
                ids.addAll(getCascadeId(menu.getId(), menus));
            }
        }
        return ids;
    }

    // 获取级联url
    protected List<String> getCascadeUrl(String id, List<Menu> menus) {
        List<String> urls = new ArrayList<>();
        for (Menu menu : menus) {
            if (menu.getPId().equals(id)) {
                if (!StringUtils.isEmpty(menu.getMenuHref())) {
                    urls.add(menu.getMenuHref());
                }
                urls.addAll(getCascadeId(menu.getId(), menus));
            }
        }
        return urls;
    }
}
